package com.citicup.backend.service.FundService;


import com.citicup.backend.dao.FundDailyMapper;
import com.citicup.backend.dao.FundInfoMapper;
import com.citicup.backend.dao.StockDailyMapper;
import com.citicup.backend.entity.FundDaily;
import com.citicup.backend.entity.FundInfo;
import com.citicup.backend.util.DateUtil;
import com.citicup.backend.webmagic.FundProcessor;
import com.citicup.backend.webmagic.MysqlPipeline;
import com.citicup.backend.webmagic.StockProcessor;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.chrome.ChromeOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.util.Pair;
import org.springframework.stereotype.Service;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.downloader.selenium.SeleniumDownloader;
import us.codecraft.webmagic.scheduler.BloomFilterDuplicateRemover;
import us.codecraft.webmagic.scheduler.QueueScheduler;
import com.citicup.backend.vo.ResponseVO;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Slf4j
public class FundService {
    @Autowired
    FundInfoMapper fundInfoMapper;
    @Autowired
    FundDailyMapper fundDailyMapper;
    @Autowired
    FundInfoMapper fundMapper;
    @Autowired
    StockDailyMapper stockDailyMapper;
    @Autowired
    FundProcessor fundProcessor;
    @Autowired
    MysqlPipeline mysqlPipeline;
    @Autowired
    StockProcessor stockProcessor;

    /*@Autowired
    public FundService(FundInfoMapper fundMapper, FundProcessor fundProcessor, MysqlPipeline mysqlPipeline) {
        this.fundMapper = fundMapper;
        this.fundProcessor = fundProcessor;
        this.mysqlPipeline = mysqlPipeline;
    }*/

    public ResponseVO showFundList() {
        //从fund_info表里得到fund_code和日期数据，再通过两者数据从fund_daily里获取数据
        //一个基金的数据不是每日更新的，更新频率也不尽相同，故而不能通过今天的日期来获取数据
        FundSortList fundSortlist = new FundSortList();

        for (FundInfo fund : fundMapper.findAll()) {
            fundSortlist.add(fund, fundDailyMapper.findByFundCodeAndDate(fund.getFundCode(), fund.getDate()).get(0));
        }

        fundSortlist.sort();

        List<Pair<FundInfo, FundDaily>> pairs = fundSortlist.getResult();

//        System.out.println("50个基金的平均月涨幅："+fundSortlist.getAveMonthRate());
        Date dNow = new Date();
        Date oneMonth = new Date(dNow.getTime() - 1000 * 3600 * 24 * 30L);
        SimpleDateFormat ft = new SimpleDateFormat("yy-MM-dd");
        double huShenNow = stockDailyMapper.findByDate(ft.format(dNow)).get(0).getCsi300();
        double huShen1Month = stockDailyMapper.findByDate(ft.format(oneMonth)).get(0).getCsi300();
//        System.out.println("沪深300的平均月涨幅："+(huShenNow/huShen1Month-1)*100);
        Map<String, Object> data = new TreeMap<>();
        data.put("fundInfo", pairs);
        data.put("FundAveMonthRate", fundSortlist.getAveMonthRate());
        data.put("Csi300AveMonthRate", (huShenNow / huShen1Month - 1) * 100);


        ResponseVO responseVO;
        if (pairs.size() > 0) {
            responseVO = ResponseVO.buildSuccess(pairs.size() + "", data);
        } else {
            responseVO = ResponseVO.buildFailure("list empty");
        }
        return responseVO;
    }

    public ResponseVO showFundByFundCode(String fundCode) {
        FundInfo fundInfo = fundMapper.findByFundCode(fundCode).get(0);
        Pair<FundInfo, FundDaily> pair = Pair.of(fundInfo, fundDailyMapper.findByFundCodeAndDate(fundInfo.getFundCode(), fundInfo.getDate()).get(0));
        ResponseVO responseVO;
        //没写返回为空的情况耶
        responseVO = ResponseVO.buildSuccess("fund found", pair);
        return responseVO;
    }

    //测试用URL
    String url = "http://fund.eastmoney.com/004745.html";

    //   private MysqlPipeline mysqlPipeline;

    //   private FundProcessor fundProcessor=new FundProcessor();

    public void updateFundInfo() {
        System.setProperty("selenuim_config", "src/main/java/com/citicup/backend/config/SelenumConfig.ini");
        //设置爬虫配置

        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.addArguments("--headless");
        //WebDriver driver = new ChromeDriver(chromeOptions);

        Spider.create(fundProcessor)
                .addUrl("http://fund.eastmoney.com")
                .setDownloader(new SeleniumDownloader("src/main/java/com/citicup/backend/webmagic/chromedriver.exe"))
                .setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(10000)))
                .thread(3) //设置线程数
                .addPipeline(mysqlPipeline) //设置持久化
                .run();
    }

    public void save(FundInfo fundInfo) {
        fundMapper.save(fundInfo);
    }

    public void updateStock() {
        System.setProperty("selenuim_config", "src/main/java/com/citicup/backend/config/SelenumConfig.ini");
        //设置爬虫配置
        Spider.create(stockProcessor)
                .addUrl("http://quote.eastmoney.com/center/hszs.html")
                .setDownloader(new SeleniumDownloader("src/main/java/com/citicup/backend/webmagic/chromedriver.exe"))
                .setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(10000)))
                .thread(2) //设置线程数
                .addPipeline(mysqlPipeline) //设置持久化
                .run();
    }


    public void calretrait() {
        for(FundInfo each:fundInfoMapper.findAll()) {
            String fundcode = each.getFundCode();
            List<FundDaily> list = fundDailyMapper.findByFundCode(fundcode);
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            String current = df.format(System.currentTimeMillis()).substring(2);
            String halfyear = DateUtil.lastDay(current, 180);
            DateUtil lhxeatshit = new DateUtil(halfyear);
            double min = 2147483647;
            double max = 0;
            for (FundDaily p : list) {
                String lhxis = p.getDate();
                DateUtil lhxisdxyson = new DateUtil(lhxis);
                if (DateUtil.early(lhxeatshit, lhxisdxyson)) {
                    if (p.getValue() > max) max = p.getValue();
                    if (p.getValue() < min) min = p.getValue();
                }
            }
            double lhx = (max - min) / max;
            List<FundInfo> list1 = fundMapper.findByFundCode(fundcode);
            FundInfo fundInfo = list1.get(0);
            fundInfo.setMaxRetraceRate(lhx);
            fundMapper.save(fundInfo);
        }
    }
      public void calfangcha(){
        for(FundInfo each:fundInfoMapper.findAll()) {
            String fundcode = each.getFundCode();
            double[] cal=new double[20];
            int head=0;
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            String current = df.format(System.currentTimeMillis()).substring(2);
            String oneyear = DateUtil.lastDay(current, 360);
            while (DateUtil.early(new DateUtil(oneyear),new DateUtil(current)) &&head<12){
                List<FundDaily> list=fundDailyMapper.findByFundCodeAndDate(fundcode,current);
                if (list.size()==0){
                    current=DateUtil.lastDay(current,1);
                }else{
                    FundDaily fundDaily=list.get(0);
                    head++;
                    cal[head]=fundDaily.getValue();
                    current=DateUtil.lastDay(current,30);
                }
            }
            double[] ca=new double[100];
            for (int j=1;j<head;j++){
                ca[j]=(cal[j+1]-cal[j])/cal[j];
            }
            double average=0;
            for (int j=1;j<head;j++){
                average=average+ca[j];
            }
            average=average/head;
            double sq=0;
            for (int j=1;j<head;j++){
                sq=sq+(average-cal[j])*(average-cal[j]);
            }
            sq=sq/(head-1);
            sq=Math.sqrt(sq);
            List<FundInfo> list1 = fundMapper.findByFundCode(fundcode);
            FundInfo fundInfo = list1.get(0);
            fundInfo.setBiaoZhunCha(sq);
            fundMapper.save(fundInfo);
        }
        }

    public void getHistory() {
        System.setProperty("selenuim_config", "src/main/java/com/citicup/backend/config/SelenumConfig.ini");
        Spider.create(fundProcessor)
                .addUrl("https://www.dayfund.cn/fundvalue/519056.html")
                .setDownloader(new SeleniumDownloader("src/main/java/com/citicup/backend/webmagic/chromedriver.exe"))
                .setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(10000)))
                .thread(3) //设置线程数
                .addPipeline(mysqlPipeline) //设置持久化
                .run();
    }

    public ArrayList<String> jiefangcheng(double r1,double r2){
         ArrayList<String> ans=new ArrayList<String>();
         double w1=0.8*r2/(r1+r2);
         w1*=100;
         int t=(int) w1*10;
         w1=t/10.0;
         String ans1=w1+"%";
         double w2=0.8*r1/(r1+r2);
         t=(int) w2*10;
         w2=t/10.0;
         String ans2=w2+"%";
         ans.add(ans1);
         ans.add(ans2);
         return ans;
    }

}

